/**
 * @(#)CreatorOnKedacom.java 2011-11-7 Copyright 2011 it.kedacom.com, Inc. All
 *                           rights reserved.
 */

package com.kedacom.xmpp.demo.crossserver.pubsub;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.OfflineMessageManager;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.smackx.pubsub.AccessModel;
import org.jivesoftware.smackx.pubsub.ConfigureForm;
import org.jivesoftware.smackx.pubsub.FormType;
import org.jivesoftware.smackx.pubsub.ItemPublishEvent;
import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.PayloadItem;
import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jivesoftware.smackx.pubsub.PublishModel;
import org.jivesoftware.smackx.pubsub.SimplePayload;
import org.jivesoftware.smackx.pubsub.listener.ItemEventListener;

/**
 * 创建节点，侦听并答复询问
 * @author xiaojinghai
 * @date 2011-11-7
 */

public class CreatorOnKedacom {

	private final String serverDomain = "ts.com";
	private final String userName = "hexiaogang";
	private final String password = "888";
	private final String nodeName = "weiboNews";
	private final String resourceName = "weiboNews_creator";
	private Connection connection;
	private PubSubManager pubSubManager;
	private LeafNode node;

	public String getJid() {
		return userName + "@" + serverDomain + "/" + resourceName;
	}

	public void connect() {
		ConnectionConfiguration connConfig = new ConnectionConfiguration("xmpp.ts.com");
		// ConnectionConfiguration connConfig = new
		// ConnectionConfiguration("172.16.3.50");
		// ConnectionConfiguration connConfig = new
		// ConnectionConfiguration(serverDomain);
		connConfig.setServiceName(serverDomain);
		// connConfig.setSendPresence(false);
		connection = new XMPPConnection(connConfig);
		try {
			connection.connect();
			connection.login(userName, password, resourceName);
			System.out.println("------------------" + getJid() + "已登录------------------");
		} catch (XMPPException e) {
			XMPPError error = e.getXMPPError();
			System.out.println(error.getCode());
			throw new RuntimeException("登录失败", e);
		} catch (Exception e) {
			throw new RuntimeException("登录失败", e);
		}

	}

	public void sendFile(XMPPConnection connection, String user, File file) throws XMPPException, InterruptedException {

		System.out.println("发送文件开始" + file.getName());
		FileTransferManager transfer = new FileTransferManager(connection);
		System.out.println("发送文件给: " + user + serverDomain);
		OutgoingFileTransfer out = transfer.createOutgoingFileTransfer(user + serverDomain + "/Smack");//

		out.sendFile(file, file.getName());

		System.out.println("//////////");
		System.out.println(out.getStatus());
		System.out.println(out.getProgress());
		System.out.println(out.isDone());

		System.out.println("//////////");

		System.out.println("发送文件结束");
	}

	public void offlineMesaage() {
		OfflineMessageManager offlineManager = new OfflineMessageManager(connection);
		try {
			Iterator<Message> it = offlineManager.getMessages();

			System.out.println(offlineManager.supportsFlexibleRetrieval());
			System.out.println("离线消息数量: " + offlineManager.getMessageCount());

			Map<String, ArrayList<Message>> offlineMsgs = new HashMap<String, ArrayList<Message>>();

			while (it.hasNext()) {
				Message message = it.next();
				System.out.println("收到离线消息, Received from 【" + message.getFrom() + "】 message: " + message.getBody());
				String fromUser = message.getFrom().split("/")[0];

				if (offlineMsgs.containsKey(fromUser)) {
					offlineMsgs.get(fromUser).add(message);
				} else {
					ArrayList<Message> temp = new ArrayList<Message>();
					temp.add(message);
					offlineMsgs.put(fromUser, temp);
				}
			}

			// 在这里进行处理离线消息集合......
			// Set<String> keys = offlineMsgs.keySet();
			// Iterator<String> offIt = keys.iterator();
			// while (offIt.hasNext()) {
			// String key = offIt.next();
			// ArrayList<Message> ms = offlineMsgs.get(key);
			// TelFrame tel = new TelFrame(key);
			// ChatFrameThread cft = new ChatFrameThread(key, null);
			// cft.setTel(tel);
			// cft.start();
			// for (int i = 0; i < ms.size(); i++) {
			// tel.messageReceiveHandler(ms.get(i));
			// }
			// }

			offlineManager.deleteMessages();
		} catch (Exception e) {
			e.printStackTrace();
		}

		Presence presence = new Presence(Presence.Type.available);
		connection.sendPacket(presence);
	}

	public void lisenChat() {
		connection.getChatManager().addChatListener(new ChatManagerListener() {

			public void chatCreated(org.jivesoftware.smack.Chat chat, boolean createdLocally) {
				chat.addMessageListener(new MessageListener() {

					public void processMessage(org.jivesoftware.smack.Chat chat, Message message) {
						String messageBody = message.getBody();
						PacketExtension pe;

						pe = message.getExtension("composing", "http://jabber.org/protocol/chatstates");
						if (pe != null) {
							System.out.println("对方正在输入......");
							return;
						}

						pe = message.getExtension("active", "http://jabber.org/protocol/chatstates");
						if (pe != null) {
							System.out.println("接收到信息：" + messageBody);
							return;
						}

						pe = message.getExtension("paused", "http://jabber.org/protocol/chatstates");
						if (pe != null) {
							System.out.println("对方已暂停输入");
							return;
						}

						pe = message.getExtension("inactive", "http://jabber.org/protocol/chatstates");
						if (pe != null) {
							System.out.println("对方聊天窗口失去焦点");
							return;
						}

						pe = message.getExtension("gone", "http://jabber.org/protocol/chatstates");
						if (pe != null) {
							System.out.println("对方聊天窗口被关闭");
							return;
						}

						System.out.println("接收到信息：" + messageBody);

					}
				});
			}

		});
	}

	public void deleteNode() {
		try {
			if (pubSubManager == null) {
				pubSubManager = new PubSubManager(connection);
			}
			pubSubManager.deleteNode(nodeName);
		} catch (XMPPException e) {
			XMPPError error = e.getXMPPError();
			if (error.getCode() == 404) {
				// 节点不存在，忽略
			} else if (error.getCode() == 409) {
				// 节点已存在，忽略
			} else {
				throw new RuntimeException("删除失败", e);
			}
		}
	}

	public void createNode() {

		try {
			// 创建一个带配置的结点/主题
			ConfigureForm form = new ConfigureForm(FormType.submit);
			form.setTitle("PubSub演示节点");// 设置说明信息
			form.setAccessModel(AccessModel.open);// 设置访问模式:open,authorize,presence,roster,whitelist
			form.setPublishModel(PublishModel.open);// 设置发布模式:open,publishers,subscribers
			// form.setItemReply(ItemReply.publisher); // 设置回复模式:owner,publisher

			form.setDeliverPayloads(true); // 设置消息中是否带有效载荷（信息）
			form.setMaxPayloadSize(1024); // 有效载荷（信息）最大字节数

			form.setPersistentItems(true); // 是否持久化存储节点中的消息

			form.setMaxItems(10); // 持久化存储的最大消息数量，前提是设置了持久化存储setPersistentItems(true)

			form.setNotifyConfig(true); // 是否发送节点配置被修改通知
			form.setNotifyDelete(true); // 是否发送节点被删除消息
			form.setNotifyRetract(true); // 是否发出节点中消息被删除的通知

			form.setPresenceBasedDelivery(false); // 是否只将消息发送给已出席的用户

			// form.setReplyRoom(List<String>);//回复给聊天室
			// form.setReplyTo(List<String>);//回复给某人

			node = (LeafNode) pubSubManager.createNode(nodeName, form);
			System.out.println("节点创建成功Id：" + node.getId());
		} catch (XMPPException e) {
			XMPPError error = e.getXMPPError();
			if (error.getCode() == 404) {
				// 节点不存在，忽略
			} else if (error.getCode() == 409) {
				// 节点已存在，忽略
			} else {
				throw new RuntimeException("新建节点失败", e);
			}
		}
	}

	public void listenToNode() {
		pubSubManager = new PubSubManager(connection);
		try {
			node = (LeafNode) pubSubManager.getNode(nodeName);
			node.addItemEventListener(new ItemEventListener<PayloadItem<SimplePayload>>() {

				public void handlePublishedItems(ItemPublishEvent<PayloadItem<SimplePayload>> event) {
					System.out.println(getJid() + "收到消息:");
					List<PayloadItem<SimplePayload>> items = event.getItems();
					for (PayloadItem<SimplePayload> item : items) {
						SimplePayload payload = item.getPayload();
						System.out.println("payload xml:" + payload.toXML());
					}
				}
			});
			node.subscribe(userName + "@" + serverDomain);
			System.out.println("正在侦听：" + nodeName);
		} catch (XMPPException e) {
			// TODO 尚未处理异常
			e.printStackTrace();
		}

	}

	public void holdOn() {
		while (true) {// 驻留主线程
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO 尚未处理异常
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		// Connection.DEBUG_ENABLED = true;
		CreatorOnKedacom creator = new CreatorOnKedacom();
		creator.connect();
		creator.deleteNode();
		creator.createNode();
		creator.offlineMesaage();
		creator.lisenChat();
		creator.holdOn();
		// Thread.currentThread().suspend();
	}
}
